from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy

# --- 初始化 ---
# 创建 Flask 应用实例
app = Flask(__name__)


# 从 config.py 文件加载配置
app.config.from_pyfile('config.py')

# 创建 SQLAlchemy 数据库实例
# db 对象是我们在应用中用来与数据库交互的主要接口
db = SQLAlchemy(app)


# --- 模型定义 ---
# Java开发者可以将其理解为JPA中的实体(Entity)类。
# 这个类定义了数据库中的一个表结构。
class User(db.Model):
    # __tablename__ 定义了在数据库中对应的表名
    __tablename__ = 'users'

    # 定义字段/列
    # db.Column 定义了一个列
    # db.Integer, db.String 是列的数据类型
    # primary_key=True 表示这是主键
    # unique=True 表示该列的值必须唯一
    # nullable=False 表示该列不接受NULL值
    id = db.Column(db.Integer, primary_key=True)
    # name = db.Column(db.String(80), unique=True, nullable=False)
    name = db.Column(db.String(80), nullable=False)
    # email = db.Column(db.String(120), unique=True, nullable=False)
    email = db.Column(db.String(120),  nullable=False)

    # 这是一个可选的构造函数，方便我们创建实例
    def __init__(self, name, email):
        self.name = name
        self.email = email

    # 这个方法定义了如何将User对象转换为可以被JSON序列化的字典
    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'email': self.email
        }


# --- 数据库表创建 ---
# 这个命令需要在第一次运行应用前执行，以创建所有定义的表。
# 我们可以通过在终端中运行 `flask shell` 进入一个特殊的Python REPL来执行它。
# 只需要执行一次即可。
@app.cli.command('init-db')
def init_db_command():
    """创建数据库表"""
    db.create_all()
    print('Initialized the database.')


# --- API 路由定义 ---
# @app.route 是一个装饰器，它告诉Flask哪个URL应该触发我们的函数。
# methods=['POST'] 指定了这个路由只接受POST请求。

# 创建用户 (Create)
@app.route('/users', methods=['POST'])
def create_user():
    # request.get_json() 从请求体中解析JSON数据
    data = request.get_json()
    if not data or not 'name' in data or not 'email' in data:
        return jsonify({'message': 'Missing data'}), 400

    # 创建一个新的User对象实例
    new_user = User(name=data['name'], email=data['email'])

    # db.session.add() 将新对象添加到数据库会话中 (类似于Hibernate的session.save())
    db.session.add(new_user)
    # db.session.commit() 将会话中的所有更改提交到数据库
    db.session.commit()

    # jsonify() 将Python字典转换为JSON格式的响应
    # 201 Created 是HTTP状态码，表示资源创建成功
    return jsonify(new_user.to_dict()), 201


# 获取所有用户 (Read All)
@app.route('/users', methods=['GET'])
def get_all_users():
    # User.query.all() 执行查询，返回所有User记录
    users = User.query.all()
    # 使用列表推导式将所有用户对象转换为字典列表
    return jsonify([user.to_dict() for user in users])


# 获取单个用户 (Read One)
@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    # User.query.get_or_404(user_id) 查询指定ID的用户，如果找不到，会自动返回404 Not Found错误
    user = User.query.get_or_404(user_id)
    return jsonify(user.to_dict())

# 更新用户 (Update)
@app.route('/users/<int:user_id>', methods=['PUT'])
def update_user(user_id):
    user = User.query.get_or_404(user_id)
    data = request.get_json()

    # 更新对象的属性
    user.name = data.get('name', user.name)
    user.email = data.get('email', user.email)

    # 只需提交会话即可保存更改
    db.session.commit()
    return jsonify(user.to_dict())



# 删除用户 (Delete)
@app.route('/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
    user = User.query.get_or_404(user_id)
    # db.session.delete() 将对象标记为删除
    db.session.delete(user)
    db.session.commit()
    return jsonify({'message': 'User deleted successfully'})




@app.route('/')
def hello_world():  # put application's code here
    return 'Hello World!'


# if __name__ == '__main__':
#     app.run()

# --- 应用启动 ---
# 这段代码确保只有在直接运行这个脚本时，才会启动开发服务器。
# 如果这个文件被其他文件导入，则不会执行。
if __name__ == '__main__':
    # 运行Flask内置的开发服务器
    # host='0.0.0.0' 使服务器可以从你的网络中的任何IP访问，而不仅仅是本地。
    # debug=True 会在代码更改后自动重启服务器，并提供详细的错误页面。生产环境中必须关闭！
    app.run(host='0.0.0.0', port=5000, debug=True)
